home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_02_03 / 2n03050a < prev    next >
Text File  |  1991-01-14  |  11KB  |  401 lines

  1.  
  2. /********************************************************************
  3. * BEZDIS.C -- Interactive Bezier Curve Display.
  4. *
  5. * Author : Bob Zigon
  6. * Date   : July 26, 1989
  7. ********************************************************************/
  8. #include "stdio.h"
  9. #include "stdlib.h"
  10. #include "string.h"
  11. #include "bios.h"
  12. #include "graphics.h"
  13.  
  14. #include "keys.h"
  15.  
  16. /*******************************************************************
  17. *                       Global Defines
  18. ********************************************************************/
  19. #define OFF           0
  20. #define ON           (!OFF)
  21.  
  22. #define MAXTDivisions 150
  23. #define MINTDivisions 30
  24. #define MAXCP         10
  25. #define CPDx          0.05
  26. #define CPDy          0.05
  27.  
  28. /*******************************************************************
  29. *                      Variable Declarations
  30. ********************************************************************/
  31. double XCp[MAXCP+1],        /* X Control Points */
  32.        YCp[MAXCP+1];        /* Y Control Points */
  33.  
  34. short int XCpScr[MAXCP+1],
  35.           YCpScr[MAXCP+1];
  36.  
  37. double XCurve[MAXTDivisions+1],   /* X Curve Points */
  38.        YCurve[MAXTDivisions+1];   /* Y Curve Points */
  39.  
  40. short int Xv[MAXTDivisions+1],
  41.           Yv[MAXTDivisions+1];
  42.  
  43. short int XvpMin,                 /* Viewport dimensions */
  44.           XvpMax,
  45.           YvpMin,
  46.           YvpMax,
  47.           XsMax,                  /* Screen Dimensions in pixels */
  48.           YsMax;
  49.  
  50. short int TDivisions = MINTDivisions,
  51.           NumCP,
  52.           CurCP = 0,
  53.           Refresh = ON;
  54.  
  55. short int CurveColor,
  56.           LineColor,
  57.           CrossColor,
  58.           BgdColor;
  59.  
  60. double XCpMin = 0.0,
  61.        XCpMax = 5.0,
  62.        YCpMin = 0.0,
  63.        YCpMax = 5.0;
  64.  
  65. char *HelpMsg[] =
  66. {
  67.    " F1    - Help",
  68.    " F2    - Toggle refresh of CP line segments",
  69.    " ",
  70.    " Left  - Move current CP left 1 unit",
  71.    " Right - Move current CP right 1 unit",
  72.    " Up    - Move current CP up 1 unit",
  73.    " Down  - Move current CP down 1 unit",
  74.    " ",
  75.    " PgUp  - Next CP",
  76.    " PgDn  - Prev CP",
  77.    " Ins   - Insert CP",
  78.    " Del   - Delete CP",
  79.    " ",
  80.    " Home  - Add 5 to number of parametric divisions",
  81.    " End   - Sub 5 from number of parametric divisions ",
  82.    " ",
  83.    " ESC   - QUIT"
  84. };
  85.  
  86. #define NUMHELP  (sizeof(HelpMsg)/sizeof(char *))
  87.  
  88. /*******************************************************************
  89. *                       Function Prototypes
  90. ********************************************************************/
  91. void Binomial(short int NumControl), UpdateStatus(void);
  92. void BezierToScreen(short int, short int, short int *, short int *);
  93. short int GetInput(void), Check8087(void);
  94. void Initialize(void), DrawCurve(short int), DrawCross(short int);
  95. void WToVConst(void), GetHelp(void);
  96.  
  97. void main()
  98. {
  99.    short int i, cc;
  100.  
  101.    Initialize();
  102.  
  103.    WToVConst();
  104.    Binomial(NumCP);
  105.    BezierToScreen(TDivisions, NumCP, Xv, Yv);
  106.    DrawCurve(ON);
  107.    UpdateStatus();
  108.  
  109.    while ((cc = GetInput()) != ESC)
  110.       switch (cc)
  111.       {
  112.          case F1    : GetHelp();
  113.                       break;
  114.  
  115.          case F2    : DrawCurve(OFF);
  116.                       Refresh = !Refresh;
  117.                       DrawCurve(ON);
  118.                       UpdateStatus();
  119.                       break;
  120.  
  121.          case LEFT  : if (XCp[CurCP]-CPDx > XCpMin)
  122.                       {
  123.                          DrawCurve(OFF);
  124.                          XCp[CurCP] -= CPDx;
  125.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  126.                          DrawCurve(ON);
  127.                       }
  128.                       break;
  129.  
  130.          case RIGHT : if (XCp[CurCP]+CPDx < XCpMax)
  131.                       {
  132.                          DrawCurve(OFF);
  133.                          XCp[CurCP] += CPDx;
  134.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  135.                          DrawCurve(ON);
  136.                       }
  137.                       break;
  138.  
  139.          case DOWN  : if (YCp[CurCP]-CPDy > YCpMin)
  140.                       {
  141.                          DrawCurve(OFF);
  142.                          YCp[CurCP] -= CPDy;
  143.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  144.                          DrawCurve(ON);
  145.                       }
  146.                       break;
  147.  
  148.          case UP    : if (YCp[CurCP]+CPDy < YCpMax)
  149.                       {
  150.                          DrawCurve(OFF);
  151.                          YCp[CurCP] += CPDy;
  152.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  153.                          DrawCurve(ON);
  154.                       }
  155.                       break;
  156.  
  157.          case PGUP  : if (CurCP+1 < NumCP)
  158.                       {
  159.                          DrawCross(BgdColor);
  160.                          CurCP++;
  161.                          DrawCurve(ON);
  162.                          DrawCross(CrossColor);
  163.                          UpdateStatus();
  164.                       }
  165.                       break;
  166.  
  167.          case PGDN  : if (CurCP-1 > -1)
  168.                       {
  169.                          DrawCross(BgdColor);
  170.                          CurCP--;
  171.                          DrawCurve(ON);
  172.                          DrawCross(CrossColor);
  173.                          UpdateStatus();
  174.                       }
  175.                       break;
  176.  
  177.          case HOME  : if (TDivisions+5 < MAXTDivisions)
  178.                       {
  179.                          DrawCurve(OFF);
  180.                          TDivisions += 5;
  181.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  182.                          DrawCurve(ON);
  183.                          UpdateStatus();
  184.                       }
  185.                       break;
  186.  
  187.          case END   : if (TDivisions-5 >= MINTDivisions)
  188.                       {
  189.                          DrawCurve(OFF);
  190.                          TDivisions -= 5;
  191.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  192.                          DrawCurve(ON);
  193.                          UpdateStatus();
  194.                       }
  195.                       break;
  196.  
  197.          case INS   : if (NumCP+1 < MAXCP && CurCP+1 != NumCP)
  198.                       {
  199.                          DrawCurve(OFF);
  200.                          for (i = NumCP++; i > CurCP; i--)
  201.                          {
  202.                             XCp[i] = XCp[i-1];
  203.                             YCp[i] = YCp[i-1];
  204.                          }
  205.  
  206.                          Binomial(NumCP);
  207.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  208.                          DrawCurve(ON);
  209.                          UpdateStatus();
  210.                       }
  211.                       break;
  212.  
  213.          case DEL   : if (NumCP > 2)
  214.                       {
  215.                          DrawCurve(OFF);
  216.                          for (i = CurCP, NumCP--; i < NumCP; i++)
  217.                          {
  218.                             XCp[i] = XCp[i+1];
  219.                             YCp[i] = YCp[i+1];
  220.                          }
  221.                          if (CurCP == NumCP)
  222.                             CurCP--;
  223.                          Binomial(NumCP);
  224.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  225.                          DrawCurve(ON);
  226.                          UpdateStatus();
  227.                       }
  228.                       break;
  229.       }
  230.  
  231.    closegraph();
  232. }
  233.  
  234. void Initialize()
  235. {
  236.    int Gdriver, Gmode;
  237.  
  238.    if (Check8087() == 0)
  239.    {
  240.       printf("\nNo Arithmetic Coprocessor Present.");
  241.       exit(1);
  242.    }
  243.  
  244.    detectgraph(&Gdriver, &Gmode);
  245.  
  246.    if (Gdriver < 0)
  247.    {
  248.       printf("\nError : No graphics hardware detected.");
  249.       exit(1);
  250.    }
  251.  
  252.    if (Gmode == CGAHI)
  253.       Gmode = CGAC0;
  254.  
  255.    initgraph(&Gdriver, &Gmode, "");
  256.  
  257.    XvpMin = 5;
  258.    YvpMin = 5;
  259.    XvpMax = getmaxx()-5;
  260.    YvpMax = getmaxy()-3-textheight("A");
  261.    XsMax  = getmaxx();
  262.    YsMax  = getmaxy();
  263.  
  264.    if (Gdriver == CGA)
  265.    {
  266.       BgdColor   = 0;
  267.       CurveColor = CGA_GREEN;
  268.       LineColor  = CGA_BROWN;
  269.       CrossColor = CGA_RED;
  270.    }
  271.    else
  272.    {
  273.       BgdColor   = BLACK;
  274.       CurveColor = WHITE;
  275.       LineColor  = YELLOW;
  276.       Cro